<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\BaseController;
use App\Http\Controllers\Easemob;
use App\Http\Controllers\SurveysController;
use App\Models\WechatLog;
use App\User;
use App\Util\Tool;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Validator;
use phpDocumentor\Reflection\Types\Object_;
use Symfony\Component\HttpFoundation\Request;
use App\Models\SmsLog;
use Illuminate\Support\Str;

class LoginController extends BaseController
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/home';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param array $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data, array $rule)
    {
        return Validator::make($data, $rule);
    }

    /**
     * 短信登录
     * @param Request $request
     * @param string $api_token
     * @return \Illuminate\Http\JsonResponse
     */
    public function SmsLogin(Request $request, string $api_token)
    {
        $rule = [
            'code' => 'required|numeric',
            //'captcha' => 'required',
        ];
        $valid = $this->validator($request->all(), $rule);
        if (count($valid->errors()) > 0) {
            return response()->json($valid->errors());
        }
        /*
        //检查图形验证是否为空
        if (empty($request->captcha)) {
            return $this->ResultJson(0, '请输入图形验证码', []);
        }
        //检查图形验证码是否过期
        $captcha = Tool::GetCapthCode($request->phone);
        if (empty($captcha)) {
            return $this->ResultJson(0, '图形验证码已经过期', []);
        }
        //需要检查短信验证码是正确
        if (strtolower($request->captcha) != strtolower($captcha)) {
            return $this->ResultJson(0, '图形验证码错误', []);
        }
        */
        //判断短信验证码是否为空
        if (empty($request->code)) {
            return $this->ResultJson(0, '请输入短信验证码', []);
        }
        //判断短信验证码是否过期
        $code = Tool:: GetSmsvalidator($request->phone);
        if (empty($code)) {
            return $this->ResultJson(0, '短信验证码已经过期', []);
        }
        //需要检查短信验证码是正确
        if ($request->code != $code) {
            return $this->ResultJson(0, '短信验证码错误', []);
        }
        //更新验证码为验证过了
        $this->SetCode($request->phone, $code);
        //短信认证设置失效时间
        Tool::UsetSmsCode($request->phone);
        //设置登录临时标识
        Tool::SetLoginToken($request->phone, $api_token);
        $user = User::where([['phone', $request->phone],])->first();
        if (empty($user)) {
            //注册用户
            $data['name'] = Tool::generateUniqueUsername();
            $data['phone'] = $request->phone;
            $data['password'] = bcrypt(123456);
            $data['api_token'] = $api_token;
            User::create($data);
            //重新获取数据
            $user = User::where([['phone', $request->phone],])->first();
            //注册环信
            $tool = Tool::getUserNameForIm(['type' => 1, 'user_id' => $user->id]);
            (new Easemob())->createUser($tool['username'], $tool['password']);
            //注册问卷
            (new SurveysController())->register(['type' => 1, 'user_id' => $user->id]);
        }else{
            //更新用户信息
            User::where(['phone' => $request->phone])->update([
                'api_token' => $api_token,
                'updated_at' => now(),
            ]);
        }
        //设置用户登录信息到redis
        Tool::SetAndUpToken($api_token, $request->phone);
        //设置用户登录信息到redis
//        $user = User::where(['phone' => $request->phone])->first();
        $username = 'user' . config("omnipay.Im.salt") . $user->id;
        $password = 'user' . config("omnipay.Im.salt") . $user->id;
        $tool['username'] = $username;
        $ress = (new Easemob())->outLogin($tool);
        if($ress == true){
            return $this->ResultJson(1, '验证成功', ['api_token' => $api_token, 'im_account' => $username, 'im_pass' => $password]);
        }
        return $this->ResultJson(0, '登录失败', ['api_token' => $api_token, 'im_account' => $username, 'im_pass' => $password]);

    }

    /**
     * 用户登录处理
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request)
    {

        $type = $request->type ?? '';
        $phone = $request->phone ?? '';

        //检查手机号是否空是否合法
        $rule = [
            'phone' => 'required|numeric|min:11',
        ];
        $valid = $this->validator($request->all(), $rule);
        if (count($valid->errors()) > 0) {
            return response()->json($valid->errors());
        }

        //检查手机是否合法
        if (!Tool::checkMobile($phone)) {
            return $this->ResultJson(0, '手机号码错误', []);
        }

        //检查手机号是否存在
        /*$user = User::where([['phone', $phone],])->first();
        if (empty($user)) {
            return $this->ResultJson(0, '您还没有注册', []);
        }*/
        /*
         * 频繁登录控制
         */
        /*
        $tapi_token = Tool::GetTempLoginToken($phone);
        if (!empty($tapi_token)) {
            return $this->ResultJson(0, '请您不要重复登录', ['api_token' => $tapi_token]);
        }
        */
        //创建api_token
        $api_token = Tool::RandomToken($phone);
        //短信登录
        if ($type == "sms") {
            return $this->SmsLogin($request, $api_token);
        } else {
            return $this->UserLogin($request, $api_token);
        }
    }


    public function UserLogin(Request $request, string $api_token)
    {
        $rule = [
            'phone' => 'required|numeric|min:11',
            'password' => 'required|string|min:6',
        ];
        $valid = $this->validator($request->all(), $rule);
        if (count($valid->errors()) > 0) {
            return response()->json($valid->errors());
        }
        $user = User::where([['phone', $request->phone],])->first();
        if(empty($user)){
            return $this->ResultJson(0, '该账号不存在!', []);
        }
        if ($user->status==1) {
            return $this->ResultJson(0, '该账号已注销,请联系管理员进行恢复!', []);
        }
        if (Hash::check($request->password, $user->password) == false) {
            return $this->ResultJson(0, '用户名或者密码错误', []);
        }
        //设置登录临时标识
        Tool::SetLoginToken($request->phone, $api_token);
        //更新用户信息
        User::where(['phone' => $request->phone])->update([
            'api_token' => $api_token,
            'updated_at' => now(),
        ]);
        //设置用户登录信息到redis
        $username = 'user' . config("omnipay.Im.salt") . $user->id;
        $password = 'user' . config("omnipay.Im.salt") . $user->id;
        Tool::SetAndUpToken($api_token, $request->phone);
        $tool['username'] = $username;
        $ress =  (new Easemob())->outLogin($tool);
        if($ress == true){
            return $this->ResultJson(1, '验证成功', ['api_token' => $api_token, 'im_account' => $username, 'im_pass' => $password]);
        }
    }

    /** 密码重置
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function ResetPassword(Request $request)
    {
        $rule = [
            'phone' => 'required|numeric|min:11', //new
            'code' => 'required|numeric',
            'password' => 'required|string|min:6|confirmed',
        ];
        $valid = $this->validator($request->all(), $rule);
        if (count($valid->errors()) > 0) {
            return response()->json($valid->errors());
        }
        if (empty($request->phone)) {
            return $this->ResultJson(0, '手机号码不能为空', []);
        }
        //检查手机号码是否正确
        if (!Tool::checkMobile($request->phone)) {
            return $this->ResultJson(0, '请填写正确的手号码', []);
        }
        //检查用户是否存在
        $user = $this->IssetUser($request->phone);
        if (!$user) {
            return $this->ResultJson(0, '手机号未注册', []);
        }
        if (empty($request->code)) {
            return $this->ResultJson(0, '请输入短信验证码', []);
        }
        //判断短信验证码是否过期
        $code = Tool:: GetSmsvalidator($request->phone);
        if (empty($code)) {
            return $this->ResultJson(0, '短信验证码已经过期', []);
        }
        //需要检查短信验证码是正确
        if ($request->code != $code) {
            return $this->ResultJson(0, '短信验证码错误', []);
        }
        //更新验证码为验证过了
        $this->SetCode($request->phone, $code);
        //生成token
        $api_token = Str::random(48) . md5($request->phone);
        //更新新密码
        $user->update(
            [
                'password' => bcrypt($request->password),
                'api_token' => $api_token,
            ]);
        //设置新token
        Tool::SetAndUpToken($api_token, $request->phone);
        return $this->ResultJson(1, '密码修改成功', ['api_token' => $api_token]);
    }
    
    
    
    
    /**
     * 微信登录
     */
    public function wechatLogin(Request $request)
    {
        $param = $request->input();
        if (empty($param['code'])) {
            return $this->ResultJson(0, 'code不能为空', []);
        }
//        if(Redis::get("wx_login_access_token")){
//            $resultArray = json_decode(Redis::get("wx_login_access_token"), true);
//        }else{
        $resultArray = $this->getAccessToken($param);
        if (isset($resultArray['errcode'])) {
            return $this->ResultJson(0, '授权失败', []);
        }
//        }
        $access_token = $resultArray["access_token"];
        $openid = $resultArray["openid"];
//第三步  获取用户信息
        //通过access_token + openid 获得用户所有信息,结果全部存储在$infoArray里,后面再写自己的代码逻辑
        $infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" . $access_token . "&openid=" . $openid . '&lang=zh_CN';
        $infoResult = $this->https_request($infoUrl);
        $infoArray = json_decode($infoResult, true);
//        dd($infoArray);
        if ($infoArray['openid']) {
            $info = (new User())->where([['wx_open_id', '=', $openid]])->first();
            if ($info && !empty($info->phone)) { //执行登录
                //生成token
                $api_token = Str::random(48) . md5($info->phone);
                $info->api_token = $api_token;
                $info->save();
                //环信聊天用户信息注册
                $tool = Tool::getUserNameForIm(['type' => 1, 'user_id' => $info->id]);
                (new Easemob())->createUser($tool['username'], $tool['password']);
                //注册问卷
                (new SurveysController())->register(['type' => 1, 'user_id' => $info->id]);
//        执行登录
                //设置用户登录信息到redis
                $username = 'user' . config("omnipay.Im.salt") . $info->id;
                $password = 'user' . config("omnipay.Im.salt") . $info->id;
                $tool['username'] = $username;
                (new Easemob())->outLogin($tool);
                //设置新token
                Tool::SetAndUpToken($api_token, $info->phone);
                return $this->ResultJson(1, '登录成功', ['api_token' => $api_token, 'is_phone' => 1, 'im_account' => $username, 'im_pass' => $password]);
            } elseif ($info && empty($info->phone)) { //未绑定手机号
                $lit['user_id'] = $info->id;
                $lit['is_phone'] = 0;
                return $this->ResultJson(1, '授权成功,请绑定手机号', $lit);
            } else { //授权成功
                $user = new WechatLog();
                $logs = $user->where([['open_id', '=', $openid]])->first();
                if ($logs) {
                    $lit['user_log_id'] = $logs->id;;
                    $lit['is_phone'] = 0;
                    return $this->ResultJson(1, '授权成功,请绑定手机号', $lit);
                }
                $user->open_id = $openid;
                $user->name = $infoArray['nickname'];
                $user->sex = $infoArray['sex'];
                $user->unionid = $infoArray['unionid'];
                $user->image = $infoArray['headimgurl'];
                $user->save();
                $lit['user_log_id'] = $user->id;;
                $lit['is_phone'] = 0;
                return $this->ResultJson(1, '授权成功,请绑定手机号', $lit);
            }
        }
    }

    /**
     * @param $param
     * @return mixed
     * 获取getAccessToken
     */
    public function getAccessToken($param)
    {
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . config("omnipay.WeChatLogin.APPID") .
            "&secret=" . config("omnipay.WeChatLogin.AppSecret") . "&code=" . $param['code'] . "&grant_type=authorization_code";
        $jsonResult = $this->https_request($url);
        $resultArray = json_decode($jsonResult, true);
//        if (isset($resultArray['access_token'])) {
//            Redis::setex("wx_login_access_token", $resultArray['expires_in'], $jsonResult);
//        }
        return $resultArray;
    }


    // An highlighted block

    public function https_request($url, $data = null)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }


    public function bindPhone(Request $request)
    {
        $param = $request->input();
        if (!isset($param['phone'])) {
            return $this->ResultJson(0, '手机号不能为空', []);
        }
        if (!isset($param['user_log_id'])) {
            return $this->ResultJson(0, '用户id不能为空', []);
        }
        $phone = Tool::checkMobile($param['phone']);
        if (!$phone) {
            return $this->ResultJson(0, '手机号格式不正确', []);
        }
        if (empty($param['code'])) {
            return $this->ResultJson(0, '请输入短信验证码', []);
        }
        //判断短信验证码是否过期
//        $code = Tool:: GetSmsvalidator($param['phone']);
//        if (empty($code)) {
//            return $this->ResultJson(0, '短信验证码已经过期', []);
//        }
//        //需要检查短信验证码是正确
//        if ($param['code'] != $code) {
//            return $this->ResultJson(0, '短信验证码错误', []);
//        }
//        //更新验证码为验证过了
//        $this->SetCode($param['phone'], $code);
        $log = (new WechatLog())->where([['id','=',$param['user_log_id']]])->first();
        //判断手机号是否存在
        $user = (new User())->where([['phone','=',$param['phone']]])->first();
        $api_token = Str::random(48) . md5($param['phone']);
        if ($user) {
            $user->wx_open_id = $log->open_id;
            $user->unionid = $log->unionid;
            $user->api_token = $api_token;
            $user->save();
        } else {
            $user = new User();
            $user->phone = $param['phone'];
            $user->api_token = $api_token;
            $user->wx_open_id = $log->open_id;
            $user->unionid = $log->unionid;
            $user->image = $log->image;
            $user->sex = $log->sex;
            $user->name = $log->name;
            $user->save();
        }
        //环信聊天用户信息注册
        $tool = Tool::getUserNameForIm(['type' => 1, 'user_id' => $user->id]);
        (new Easemob())->createUser($tool['username'], $tool['password']);
        //注册问卷
        (new SurveysController())->register(['type' => 1, 'user_id' => $user->id]);
//        执行登录
        //设置用户登录信息到redis
        $username = 'user' . config("omnipay.Im.salt") . $user->id;
        $password = 'user' . config("omnipay.Im.salt") . $user->id;
        $tool['username'] = $username;
        (new Easemob())->outLogin($tool);
        //设置新token
        Tool::SetAndUpToken($api_token, $param['phone']);
        return $this->ResultJson(1, '登录成功', ['api_token' => $api_token,'is_phone'=>1, 'im_account' => $username, 'im_pass' => $password]);
    }
    
    
    
    
}
